package amazon

import (
	"fmt"
	"gitee.com/wengo/go-mamba"
	"github.com/PuerkitoBio/goquery"
	"github.com/tidwall/gjson"
	"io/ioutil"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// 添加购物车
//
// document: listing页面的document
func (a *Amazon) IsAddCartSuccess(document *goquery.Document) bool {
	return document.Find(".a-alert-inline-error").Length() > 0
}

// 添加购物车
//
// document: listing页面的document
func (a *Amazon) AddCart(document *goquery.Document, qty int) (resp *mamba.Response, newDocument *goquery.Document, err error) {
	action, method, data, err := a.ExtractFormData(document, "#addToCart")
	if err != nil {
		return nil, nil, fmt.Errorf("产品页购物车 %s", err)
	}

	delete(data, "gift-wrap")
	data["quantity"] = strconv.Itoa(qty)

	resp, newDocument, err = a.Submit(action, method, nil, nil, data)

	if err != nil {
		return nil, nil, err
	}

	return
}

// 添加购物车
//
// document: offer页面的document
func (a *Amazon) AddCartByOffers(document *goquery.Document, asin, sellerId string, qty int) (quantity int64, err error) {
	body, _ := document.Html()

	if !strings.Contains(body, sellerId) {
		return 0, fmt.Errorf("没有在 %s 没找到指定的 %s 商家", asin, sellerId)
	}

	var (
		csrfToken      string
		offerListingId string
	)

	csrfToken, exists := document.Find("#aod-atc-csrf-token").Attr("value")
	endpoint, exists := document.Find("#aod-atc-ajax-endpoint").Attr("value")
	if exists {
		document.Find("#aod-offer").EachWithBreak(func(i int, selection *goquery.Selection) bool {
			link, _ := selection.Find("#aod-offer-soldBy a").Attr("href")
			offerListingId, _ = selection.Find("span[data-action='aod-atc-action']").Attr("data-aod-atc-action")
			offerListingId = gjson.Get(offerListingId, "oid").String()
			if strings.Contains(link, sellerId)  && strings.Contains(link, `isAmazonFulfilled=0`) {
				return false
			}
			return true
		})
	}

	if csrfToken != "" && offerListingId != "" {
		headers := map[string]string{
			"Accept":           `application/vnd.com.amazon.api+json; type="cart.add-items/v1"`,
			"Content-Type":     `application/vnd.com.amazon.api+json; type="cart.add-items.request/v1"`,
			"Referer":          a.client.BaseURL,
			"Accept-Language":  `en-US`,
			"x-api-csrf-token": csrfToken,
			"Origin":           a.client.BaseURL, //没有这个会400
			//"Origin": `https://www.amazon.com`,//没有这个会400
			"Connection":     "keep-alive",
			"Sec-Fetch-Dest": "empty",
			"Sec-Fetch-Mode": "cors",
			"Sec-Fetch-Site": "same-origin",
		}

		body := map[string]interface{}{
			"items": []map[string]interface{}{
				{"asin": asin, "offerListingId": offerListingId, "quantity": qty, "additionalParameters": map[string]string{}},
			},
		}

		var resp *mamba.Response
		resp, _, err = a.json(fmt.Sprintf(`https://%s`, endpoint), headers, body)

		if err != nil {
			return 0, fmt.Errorf(`无法加入购物车`)
		}

		content := resp.String()
		if gjson.Get(content, "entity.status").Int() == 400 {
			var reason string
			if gjson.Get(content, "entity.internalInfo.message").String() != "" {
				reason = gjson.Get(content, "entity.internalInfo.message").String()
			} else {
				reason = gjson.Get(content, "entity.details.message").String()
			}
			return 0, fmt.Errorf(`加入购物车失败, 原因 = %s`, reason)
		} else {
			if gjson.Get(content, "entity.items.0.quantity").Int() == 0 {
				ioutil.WriteFile("cart_error.html", []byte(content), 0644)
			}
			return gjson.Get(content, "entity.items.0.quantity").Int(), nil
		}
		//respResult, _ := newDocument.Html()
		//matcher := regexp.MustCompile(`<body>(.+?)</body>`)
		//result := matcher.FindAllStringSubmatch(respResult, -1)
		//if len(result) > 0 {
		//	if gjson.Get(html.UnescapeString(result[0][1]), "entity.status").Int() > 0 {
		//		var reason string
		//		if gjson.Get(html.UnescapeString(result[0][1]), "entity.internalInfo.message").String() != "" {
		//			reason = gjson.Get(html.UnescapeString(result[0][1]), "entity.internalInfo.message").String()
		//		} else {
		//			reason = gjson.Get(html.UnescapeString(result[0][1]), "entity.details.message").String()
		//		}
		//		return false, fmt.Errorf(`加入购物车失败, 原因 = %s`, reason)
		//	} else {
		//		return isSuccess, nil
		//	}
		//
		//}
	} else {
		if offerListingId == "" {
			return 0, fmt.Errorf("没有在 %s 下找到 %s 店铺", asin, sellerId)
		} else {
			return 0, fmt.Errorf("无法找到 %s 店铺的csrftoken", sellerId)
		}
	}

}

func (a *Amazon) CheckAddCartSuccess(document *goquery.Document) bool {
	return document.Find("#sw-atc-confirmation").Length() > 0
}

// 模拟加入购物车,检查库存
//
// document: listing页面的document
func (a *Amazon) MockAddCart(document *goquery.Document, qty int) (newDocument *goquery.Document, err error) {
	asin, _ := document.Find("#addToCart input[name='ASIN']").Attr("value")
	sessionId, _ := document.Find("#addToCart input[name='session-id']").Attr("value")
	offerListingID, _ := document.Find("#addToCart input[name='offerListingID']").Attr("value")
	data := map[string]string{
		"a":                      asin,
		"colid":                  "",
		"coliid":                 "",
		"ctaDeviceType":          "desktop",
		"ctaPageType":            "detail",
		"customId":               "",
		"o":                      "add",
		"oid":                    offerListingID,
		"quantity":               strconv.Itoa(qty),
		"rcxOrdFreq":             "",
		"rebateId":               "",
		"redirectToFullPage":     "1",
		"snsAddressId":           "",
		"snsMerchantID":          "",
		"snsMostCommonFrequency": "",
		"snsOfferListingID":      "",
		"snsOnmlOfferId":         "",
		"snsOptIn":               "",
		"verificationSessionID":  sessionId,
		"_encoding":              "UTF8",
		"ref_":                   "mw_dp_buy_crt",
		"submit.add-to-cart":     "Add to cart",
	}

	_, newDocument, err = a.Submit(`/cart`, POST, nil, data, data)

	return
}

// 获取ASIN库存
//
// document: 购物车的document
func (a *Amazon) GetStock(document *goquery.Document) map[string]string {
	//content := document.Find(".a-alert-content p").Text()
	content, _ := document.Html()

	isLimitMatcher := regexp.MustCompile(`(this seller has a limit|um limite de compra|verkoper geldt een limiet|presenta un limite di|vendedor tiene un límite de|お客様お一人あたり|Verkaufsbeschränkung|une limite de vente)`)
	if isLimitMatcher.MatchString(content) {
		limitMatcher := regexp.MustCompile(`(?:(?:Cart subtotal|カートの小計|Subtotal do carrinho|Subtotal del carrito|Subtotaal winkelwagen|Basket subtotal|Subtotale carrello|Subtotal de la cesta|Zwischensumme|Sous-total du panier).*?[(|（商品]|(?:than the |品は、|Anbieters von |has a limit of |um limite de compra |verkoper geldt een limiet |presenta un limite di |vendedor tiene un límite de |お客様お一人あたり ?|une limite de vente |momentan lediglich: |total de |quantità di |lediglich: |a que |de los |"cartCount":))([0-9]{1,6}) ?(?:(?:available|\. Klicken|de disponible|\. <a|per customer|por cliente|までと限定|per cliente|articles par client|disponibles|点のご|articoli disponibili|disponíveis,"freshCartCount"|)|(?:items?|itens?|articol[io]|Artikel|点|productos?|articles?|artículos?)[)）])`)
		result := limitMatcher.FindAllStringSubmatch(content, -1)
		return map[string]string{
			"status": "error",
			"reason": fmt.Sprintf("%s limit", result[0][1]),
		}
	}

	//if strings.Contains(content, "per customer") {
	//	return map[string]string{
	//		"status": "error",
	//		"reason": "limit",
	//	}
	//}

	matcher, _ := regexp.Compile(`than the ([\d]+) available`)
	results := matcher.FindStringSubmatch(content)

	if len(results) > 0 {
		return map[string]string{
			"status": "success",
			"qty":    results[1],
		}
	}

	html, _ := document.Html()
	ioutil.WriteFile("error.html", []byte(html), 0644)

	return map[string]string{
		"status": "error",
		"reason": "unknown",
	}
}

// 购物车更新数量
//
// document: 购物车的document
func (a *Amazon) UpdateQuantity(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
	action, _, queryData, err := a.ExtractFormData(document, "#gutterCartViewForm")
	if err != nil {
		return nil, nil, err
	}

	//queryData["cartInitiateId"] = strconv.Itoa(int(time.Now().UnixNano() / 1e6))
	queryData["isToBeGiftWrapped"] = "0"
	queryData["isToBeGiftWrappedBefore"] = "0"

	// 开始下单
	resp, newDocument, err = a.Submit(action, GET, nil, queryData, nil)

	return
}

// 结账
//
// document: 购物车的document
func (a *Amazon) Checkout(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
	action, _, queryData, err := a.ExtractFormData(document, "#gutterCartViewForm")
	if err != nil {
		return nil, nil, fmt.Errorf("购物车为空, 错误提示 %s", err)
		//return nil, nil, fmt.Errorf("购物车 %s", err)
	}

	queryData["cartInitiateId"] = strconv.Itoa(int(time.Now().UnixNano() / 1e6))
	//queryData["isToBeGiftWrapped"] = "0"
	queryData["isToBeGiftWrappedBefore"] = "1"

	// 开始下单
	resp, newDocument, err = a.Submit(action, GET, nil, queryData, nil)

	return
}
